package com.biostime.qdingding.modules.job.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.biostime.qdingding.common.service.BaseService;
import com.biostime.qdingding.common.utils.StringUtils;
import com.biostime.qdingding.modules.job.dao.AutoClearDao;
import com.biostime.qdingding.modules.qd.entity.Course;
import com.biostime.qdingding.modules.qd.entity.CourseOrder;
import com.biostime.qdingding.modules.qd.entity.Promotion;
import com.biostime.qdingding.modules.qd.push.MsgTemplate;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.CourseTip;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.QueueFail;
import com.biostime.qdingding.modules.qd.service.CourseOrderService;
import com.biostime.qdingding.modules.qd.service.CourseService;
import com.biostime.qdingding.modules.qd.service.MessageService;
import com.biostime.qdingding.modules.qd.service.OrderpromotionsService;
import com.biostime.qdingding.modules.qd.service.TransrecordService;

/**
 * 自动结算Service
 * @author phil
 * @version 2015-11-25
 */
@Service
@Transactional(readOnly = true)
public class AutoClearService extends BaseService {
	
	/**
	 * 日志对象
	 */
	protected Logger logger = LoggerFactory.getLogger("autoclear");
	
	@Autowired 
	CourseOrderService courseOrderService;
	@Autowired
	private TransrecordService transrecordService;
	@Autowired
	private OrderpromotionsService orderpromotionsService;
	@Autowired
	private AutoClearDao autoClearDao;
	@Autowired
	private AutoClearHandler autoClearHandler;
	@Autowired
	private CourseService courseService;
	@Autowired
	private MessageService messageService;
	
	/**
	 * 获取预定状态的课程
	 * @param courseCount 一次处理课程数量
	 * @return 
	 */
	public List<HashMap<String,Object>> getOrderdCourse(int courseCount, Date courseDate) {
		return autoClearDao.getOrderdCourse(courseCount, courseDate);
	}

	/**
	 * 普通课程扣费
	 * 一次会处理一个课程的所有订单
	 * @param courseId 课程ID
	 * @return 是否扣费成功
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void autoClearIn(int type, int courseId) {
		
		List<HashMap<String,Object>> orderedStudents = autoClearDao.getRankStudents(type,courseId);
		
		StringBuilder log = new StringBuilder(String.format("\n课程订单[%s:%s]: 自动扣费开始\n", type, courseId));
		
		Course course = courseService.get(String.valueOf(courseId));
		boolean hasError = false;
		
		if(course==null){ 
			log.append("==>不存在对于课程\n");
			hasError = true;
		}
		
		if(orderedStudents==null || orderedStudents.size()<=0){
			log.append("==>约课人数为0\n");
			hasError = true;
		}
		
		if(!hasError){
			int orderdCount = 0,queuedCount = 0,leavedCount = 0;
			
			//计算人数
			for(int i=0;i<orderedStudents.size();i++){
				HashMap<String,Object> orderedStudent =  orderedStudents.get(i);
				String state = (String)orderedStudent.get("state");
				
				//预约状态
				if(state.equals("ordered")){
					orderdCount++;
				}
				//请假状态
				if(state.equals("leaved")){
					leavedCount++;
				}
				//排队状态
				if(state.equals("queuing")){
					queuedCount++;
				}
			}
			log.append(String.format("==>约课人数:%s，排队人数:%s，请假人数:%s\n", orderdCount, queuedCount, leavedCount));
			
			if(/*orderdCount>=3*/ true){
				for(int i=0;i<orderedStudents.size();i++){
					HashMap<String,Object> orderedStudent =  orderedStudents.get(i);
					
					int memberId = StringUtils.toInteger(orderedStudent.get("memberId"));//会员编号
					int studentId = StringUtils.toInteger(orderedStudent.get("studentId")); //学员编号
					int orderId = StringUtils.toInteger(orderedStudent.get("id"));//订单编号
					String state = (String)orderedStudent.get("state");
					
					//预约状态的扣费
					if(state.equals("ordered") || state.equals("leaved")){
						boolean result = false;
						
						/**第一步：处理订单**/
						try{
							result = autoClearHandler.handleOrderIn(type, course, (orderdCount + leavedCount), orderedStudent, log);
						}catch(Exception ex){
							log.append(String.format("==>处理订单(%s)异常:%s %s\n", orderId, ex.getMessage(), ex.getStackTrace()));
							logger.error(String.format("==>处理订单(%s)异常\n", orderId), ex);
						}

						/**第二步：修改订单状态**/
						CourseOrder courseOrder = courseOrderService.get(String.valueOf(orderId));
						if(result){
							courseOrder.setPaid(1);
						}else{
							courseOrder.setPaid(-1);
						}
						courseOrderService.save(courseOrder);
						
						log.append(String.format("==>修改订单(%s):状态(%s)\n",courseOrder.getId(), courseOrder.getPaid()));
						
						/**第$步：发送上课消息**/
						SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
						String message = CourseTip.content;
						message = message.replace(MsgTemplate.date, df.format(course.getOndate()));
						message = message.replace(MsgTemplate.section, course.getSection());
						message = message.replace(MsgTemplate.level, course.getClevel());
						message = message.replace(MsgTemplate.serial, course.getSerial());
						message = message.replace(MsgTemplate.theme, course.getTheme());
						
						String pushMsg = CourseTip.push;
						pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
						pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
						pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
						pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
						pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
						
						messageService.sendAndPush(CourseTip.category, String.valueOf(studentId), CourseTip.title, message, String.valueOf(memberId), pushMsg);
					}
					
					//排队状态的取消约课
					if(state.equals("queuing")){
						/**第三步：排位的人取消订单**/
						CourseOrder courseOrder = courseOrderService.get(String.valueOf(orderId));
						courseOrder.setState("canceled");
						courseOrder.setRemarks("等位失败");
						courseOrderService.save(courseOrder);
						
						/**第四步：等位失败发送消息**/
						SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
						String message = QueueFail.content;
						message = message.replace(MsgTemplate.date, df.format(course.getOndate()));
						message = message.replace(MsgTemplate.section, course.getSection());
						message = message.replace(MsgTemplate.level, course.getClevel());
						message = message.replace(MsgTemplate.serial, course.getSerial());
						message = message.replace(MsgTemplate.theme, course.getTheme());
						
						String pushMsg = QueueFail.push;
						pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
						pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
						pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
						pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
						pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
						
						messageService.sendAndPush(QueueFail.category, String.valueOf(studentId), QueueFail.title, message, String.valueOf(memberId), pushMsg);
						
						log.append(String.format("==>修改订单(%s):取消排位\n",courseOrder.getId()));
					}
				}
			}
			/*else{
				//2个人不开课，课程自动取消
				for(int i=0;i<orderedStudents.size();i++){
					HashMap<String,Object> orderedStudent =  orderedStudents.get(i);
					
					int memberId = StringUtils.toInteger(orderedStudent.get("memberId"));//会员编号
					int studentId = StringUtils.toInteger(orderedStudent.get("studentId")); //学员编号
					int orderId = StringUtils.toInteger(orderedStudent.get("id"));//订单编号
					//String state = (String)orderedStudent.get("state");
					
					CourseOrder courseOrder = courseOrderService.get(String.valueOf(orderId));
					courseOrder.setState("canceled");
					courseOrder.setRemarks("不足3人，不开课");
					courseOrderService.save(courseOrder);
					
					SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
					String message = Three.content;
					message = message.replace(MsgTemplate.date, df.format(course.getOndate()));
					message = message.replace(MsgTemplate.section, course.getSection());
					message = message.replace(MsgTemplate.level, course.getClevel());
					message = message.replace(MsgTemplate.serial, course.getSerial());
					message = message.replace(MsgTemplate.theme, course.getTheme());
					
					String pushMsg = Three.push;
					pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
					pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
					pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
					pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
					pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
					
					messageService.sendAndPush(Three.category, String.valueOf(studentId), Three.title, message, String.valueOf(memberId), pushMsg);
					
					log.append(String.format("==>修改订单(%s):不足3人，不开课\n",courseOrder.getId()));
				}
			}*/
		}
		
		log.append(String.format("课程订单[%s:%s]: 自动扣费完成", type, courseId));
		logger.info(log.toString());
	}

	/**
	 * 户外课程扣费
	 * @param courseId 课程ID
	 * @return 是否扣费成功
	 */
	@Deprecated
	public void autoClearOut(int type, int courseId) {
		
		List<HashMap<String,Object>> orderedStudents = autoClearDao.getRankStudents(type,courseId);
		
		StringBuilder log = new StringBuilder(String.format("\n课程订单[%s:%s]: 自动扣费开始\n", type, courseId));
		
		Course course = courseService.get(String.valueOf(courseId));
		boolean hasError = false;
		
		if(orderedStudents==null || orderedStudents.size()<=0){
			log.append("==>约课人数为0\n");
			hasError = true;
		}
		
		if(!hasError){
			int orderdCount = orderedStudents.size();
			log.append(String.format("==>约课人数为%s\n", orderdCount));
			
			for(int i=0;i<orderedStudents.size();i++){
				
				HashMap<String,Object> orderedStudent = orderedStudents.get(i);
				
				int orderId = StringUtils.toInteger(orderedStudent.get("id"));//订单编号
				
				if(i<course.getCapacity()){
					/**第一步：处理订单**/
					boolean result = false;
					try{
						result = autoClearHandler.handleOrderOut(type, courseId, orderdCount, orderedStudent, log);
					}catch(Exception ex){
						log.append(String.format("==>处理订单(%s)异常:%s %s\n", orderId, ex.getMessage(), ex.getStackTrace()));
						logger.error(String.format("==>处理订单(%s)异常\n", orderId), ex);
					}
					
					/**第二步：修改订单状态**/
					CourseOrder courseOrder = courseOrderService.get(String.valueOf(orderId));
					if(result){
						courseOrder.setPaid(1);
					}else{
						courseOrder.setPaid(-1);
					}
					courseOrderService.save(courseOrder);
					
					log.append(String.format("==>修改订单(%s):状态(%s)\n",courseOrder.getId(), courseOrder.getPaid()));
				}else{
					
					/**第三步：排位的人取消订单**/
					CourseOrder courseOrder = courseOrderService.get(String.valueOf(orderId));
					courseOrder.setState("canceled");
					courseOrderService.save(courseOrder);
					
					log.append(String.format("==>修改订单(%s):取消排位\n",courseOrder.getId()));
				}
			}
		}
		
		log.append(String.format("课程订单[%s:%s]: 自动扣费完成", type, courseId));
		logger.info(log.toString());
	}
	
	/**
	 * 获取学员所有优惠
	 * @param studentId 学员编号
	 * @return
	 */
	public List<Promotion> getPromotions(int studentId) {
		return autoClearDao.getPromotions(studentId);
	}

}
